package com.javaxiaobang.es.lucene;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.util.IOUtils;
import com.javaxiaobang.es.constant.EsConstants;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 功    能：lucene
 * 作    者：java潇邦
 * 时    间：2020/5/4
 */
public class LuceneMain {

    /**
     * 源码地址：https://gitee.com/sunrisexq/es
     */
    public static void main(String[] args) {
        //1、创建索引
        createIndex(EsConstants.INDEX_DATA_DIR);
        //2、添加索引文档
        addIndexDoc(EsConstants.INDEX_DATA_DIR, EsConstants.JSON_CONTENT);
        //3、查询内容
        query(EsConstants.INDEX_DATA_DIR, "歌手","杰伦");
    }

    /**
     * 创建索引
     *
     * @param indexDir 索引存放位置
     */
    public static void createIndex(String indexDir) {
        IndexWriter writer = null;
        try {
            //获取目录
            Directory directory = FSDirectory.open(Paths.get(indexDir));
            //设置分词器
            Analyzer analyzer = new StandardAnalyzer();
            //准备config
            IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
            //创建lucene实例
            writer = new IndexWriter(directory, indexWriterConfig);
            System.out.println("索引创建成功");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IOUtils.close(writer);
        }
    }

    /**
     * 添加索引文档
     *
     * @param indexDir    索引存放位置
     * @param jsonContent json内容
     */
    public static void addIndexDoc(String indexDir, String jsonContent) {
        IndexWriter writer = null;
        try {
            //获取目录
            Directory directory = FSDirectory.open(Paths.get(indexDir));
            //设置分词器
            Analyzer analyzer = new StandardAnalyzer();
            //准备config
            IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
            //创建lucene实例
            writer = new IndexWriter(directory, indexWriterConfig);
            Document document = jsonToDoc(jsonContent);
            writer.addDocument(document);
            System.out.println("索引文档添加成功");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IOUtils.close(writer);
        }
    }

    /**
     * json内容转document文档
     *
     * @param jsonContent json内容
     * @return
     */
    public static Document jsonToDoc(String jsonContent) {
        Document document = new Document();
        JSONObject jsonObj = JSONObject.parseObject(jsonContent);
        Set<Map.Entry<String, Object>> entrySet = jsonObj.entrySet();
        for (Map.Entry<String, Object> entry : entrySet) {
            document.add(new TextField(entry.getKey(), entry.getValue() == null ? "" : entry.getValue().toString(), Field.Store.YES));
        }
        return document;
    }

    /**
     * 查询文档
     * @param indexDir 索引存放位置
     * @param queryParam 查询条件
     * @param queryContent 查询单词内容
     * @return
     */
    public static String query(String indexDir, String queryParam, String queryContent) {
        StringBuilder result = new StringBuilder();
        IndexReader reader = null;
        try {
            //获取目录
            Directory directory = FSDirectory.open(Paths.get((indexDir)));
            //获取reader
            reader = DirectoryReader.open(directory);
            //获取索引实例
            IndexSearcher searcher = new IndexSearcher(reader);
            //设置分词器
            Analyzer analyzer = new StandardAnalyzer();
            //创建解析器
            QueryParser queryParser = new QueryParser(queryParam, analyzer);
            Query query = queryParser.parse(queryContent);
            TopDocs topDocs = searcher.search(query, 10);
            System.out.println("topDocs内容:" + JSON.toJSONString(topDocs));
            for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
                //拿到文档实例
                Document document = searcher.doc(scoreDoc.doc);
                //获取所有文档字段
                List<IndexableField> fieldList = document.getFields();
                 //处理文档字段
                for (IndexableField field:fieldList){
                    result.append(field.name());
                    result.append(":");
                    result.append(field.stringValue());
                    result.append(",\r\n");
                }
            }
            System.out.println("查询结果："+result);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            IOUtils.close(reader);
        }
        return result.toString();
    }

}
